﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using WeifenLuo.WinFormsUI.ThemeVS2012;
using WeifenLuo.WinFormsUI;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Diagnostics;

namespace Frame
{
    interface IPluginFactory
    {
        Plugin CreatePlugin(FrameApplication app);
    }
    public class PluginManager
    {
        private DockPanel panel;

        Dictionary<string, Plugin> windowDic;
        Dictionary<string, Type> TypeDictionary;

        Dictionary<string, List<Plugin>> menuDictionary; //窗口与菜单对应<菜单，窗口列表>


        FrameApplication m_app;
        public PluginManager(FrameApplication app)
        {
            Stopwatch sw = new Stopwatch();
            m_app = app;

            menuDictionary = new Dictionary<string, List<Plugin>>();
            windowDic = new Dictionary<string, Plugin>();
            TypeDictionary = new Dictionary<string, Type>();

            panel = new DockPanel();
            app.MainForm.Controls.Add(panel);
            panel.BringToFront();
            panel.Dock = DockStyle.Fill;
            panel.Theme = new VS2012BlueTheme();
            panel.DefaultFloatWindowSize = new Size(600, 400);
            panel.MinimumSize = new Size(100, 100);
            panel.DockLeftPortion = 200;
            panel.DockRightPortion = 300;
            panel.DockBottomPortion = 220;

            LoadPlugins();
          
        }

        public Dictionary<string, Type> GetPluginTypes()
        {
            return TypeDictionary;
        }


        public void save(string path)
        {
            panel.SaveAsXml(path);
        }

        IDockContent getDockContenct(string persistString)
        {
            for (int i = 0; i < windowDic.Count; i++)
            {
                Type t = TypeDictionary.ElementAt(i).Value;
                string _s = windowDic.ElementAt(i).Value.GetType().Namespace + "." + windowDic.ElementAt(i).Value.GetType().Name;
                if (_s == persistString)
                {
                    return windowDic.ElementAt(i).Value;
                }
            }
            return null;
        }



        public void load(string path)
        {
            if (File.Exists(path))
            {
                panel.LoadFromXml(path, getDockContenct);
            }
        }
        
        //加载各个功能窗体，通过窗体中的Plugin类加载
        void LoadPlugins()
        {
            List<string> pluginpath = new List<string>();
            string path = AppDomain.CurrentDomain.BaseDirectory;
            path = Path.Combine(path, "Plugins");
            if (!Directory.Exists(path))
            {
                // 如果目录不存在，则创建它
                Directory.CreateDirectory(path);
                return;
            }
            string[] files = Directory.GetFiles(path, "*.dll");
            if (files.Count() <= 0) return;
            foreach (string fileName in files)
            {
                pluginpath.Add(fileName);
            }

            foreach (string filename in pluginpath)
            {
                try
                {
                    //获取文件名
                    string asmfile = filename;
                    string asmname = Path.GetFileNameWithoutExtension(asmfile);
                    if (asmname != string.Empty)
                    {
                        //利用反射,构造DLL文件的实例
                        Assembly asm = Assembly.LoadFile(asmfile);
                        //利用反射,从程序集(DLL)中,提取类,并把此类记录,以用作后续实例化
                        Type[] t = asm.GetExportedTypes();
                        foreach (Type type in t)
                        {
                            if (type.IsSubclassOf(typeof(Plugin)))
                            {
                                //MethodInfo md = type.GetMethod("GetPluginName");
                                //if (md == null)
                                //    break;
                                //string _t = (string)md.Invoke(null, null);
                                //TypeDictionary.Add(type.Name, type);
                                TypeDictionary.Add(type.FullName, type);
                            }
                        }
                    }
                }
                catch (Exception /*ex*/)
                {

                }
            }
            //sw.Stop();
            //MessageBox.Show(sw.ElapsedMilliseconds.ToString());
        }

        /// <summary>
        /// 创建可放入布局中的默认窗口,创建一次后返回窗口句柄
        /// </summary>
        /// <param name="name">窗口名称</param>
        /// <returns></returns>
        public Plugin CreatePlugin(string name)
        {
            if (TypeDictionary.ContainsKey(name))
            {
                if (windowDic.ContainsKey(name))
                {
                    return windowDic[name];
                }
                else
                {
                    Plugin p = (Plugin)Activator.CreateInstance(TypeDictionary[name], new object[] { m_app });
                    Console.WriteLine(p.DockState);
                    p.DefaultDockState = DockState.Document;
                    p.Panel = panel;
                    windowDic.Add(name, p);
                    //windowNameDic.Add(p.Text, p.Type);
                    AddMenu(p);
                }
                return windowDic[name];
            }
            else
                return null;
        }

        /// <summary>
        /// 创建可放入布局中的默认窗口,创建一次后返回窗口句柄
        /// </summary>
        /// <param name="type">窗口类型</param>
        /// <returns></returns>
        //public Plugin CreatePlugin(PluginType type, Menu.MenuType menu)
        //{
        //    if (TypeDictionary.ContainsKey(type))
        //    {
        //        if (windowDic.ContainsKey(type))
        //        {
        //            return windowDic[type];
        //        }
        //        else
        //        {
        //            Plugin p = (Plugin)Activator.CreateInstance(TypeDictionary[type], new object[] { m_app });
        //            p.DefaultDockState = GetState(p.Type);
        //            p.Panel = panel;
        //            windowDic.Add(type, p);
        //            AddMenu(p);

        //        }
        //        return windowDic[type];
        //    }
        //    else
        //        return null;
        //}
        /// <summary>
        /// 创建独立窗口,只能悬浮,不受当前活动卡和轴影响
        /// </summary>
        /// <param name="type"></param>
        /// <param name="app"></param>
        public void CreatePlugin(string type, FrameApplication app)
        {
            Plugin p = (Plugin)Activator.CreateInstance(TypeDictionary[type], new object[] { app });
            p.HideOnClose = false;
            p.InitUI();
            p.Show();
        }

        //DockState GetState(PluginType type)
        //{
        //    DockState state = DockState.Document;
        //    switch (type)
        //    {
        //        //case PluginType.CardList:
        //        //    state = DockState.DockLeft;
        //        //    break;
        //        //case PluginType.DriveInfo:
        //        //    state = DockState.DockBottom;
        //        //    break;           
        //        //case PluginType.Log:
        //        //    state = DockState.DockBottom;
        //        //    break;
        //        default:
        //            state = DockState.Document;
        //            break;
        //    }
        //    return state;
        //}

        public void Initialize()
        {
            for (int i = 0; i < windowDic.Count; i++)
            {
                Plugin toolWindow = windowDic.ElementAt(i).Value;
                if (m_app.MainForm.InvokeRequired)
                {
                    m_app.MainForm.Invoke(new Action(toolWindow.InitUI));                    
                }
                else
                {
                    toolWindow.InitUI();
                }
            }
        }

        public Plugin GetPluin(string name)
        {
            foreach(Plugin win in windowDic.Values)
            {
                if(win.Text.Contains(name))
                {
                    return win;
                }
            }
            return null;
        }

        //public PluginType GetPluinType(string name)
        //{
        //    if (!windowNameDic.ContainsKey(name))
        //        return PluginType.Default;
        //    return windowNameDic[name];
        //}

        //public List<Plugin> GetMenuList(Menu.MenuType type)
        //{
        //    List<Plugin> p = new List<Plugin>();
        //    if (menuDictionary.ContainsKey(type))
        //        p = menuDictionary[type];
        //    return p;
        //}

        public List<Plugin> GetMenuList(string menu_name)
        {
            List<Plugin> p = new List<Plugin>();
            if (menuDictionary.ContainsKey(menu_name))
                p = menuDictionary[menu_name];
            return p;
        }

        public void AddMenu(Plugin p)
        {
            List<Plugin> pList;
            if (!menuDictionary.ContainsKey(p.OnMenu))
            {
                pList = new List<Plugin>();
                menuDictionary.Add(p.OnMenu, pList);
            }
            else
            {
                pList = menuDictionary[p.OnMenu];

            }
            pList.Add(p);
            menuDictionary[p.OnMenu] = pList;
        }

        public void CloseAllWindows()
        {
            //foreach (var item in Enum.GetValues(typeof(Menu.MenuType)))
            //{
            //    Menu.MenuType type = (Menu.MenuType)item;
            //    List<Plugin> win = GetMenuList(type);
            //    foreach(Plugin p in win)
            //    {
            //        p.Close();
            //    }
            //}

            foreach(List<Plugin> plugins in menuDictionary.Values)
            {
                foreach (Plugin win in plugins)
                {
                    win.Close();
                }
            }

        }
    }
}
